/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spring;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import phys.State;
import vec.Vector3f;

/**
 *
 * @author Vic
 */
public class Spring extends Element {
    static final int COILS=10;
    float length;
    float stiffness;
    float dampeningFactor;
    Vector3f start;

    public Spring(float length, float stiffness, float dampening, Vector3f start) {
        this.length = length;
        this.stiffness = stiffness;
        this.dampeningFactor = dampening;
        this.start = start;
        state = new State();
    }

    @Override
    public void draw(Graphics g,Vector3f origen) {
        Graphics2D g2d=(Graphics2D) g;
        Vector3f end = new Vector3f(state.getPosition());            //the end of the Spring, the circle
        Vector3f last = new Vector3f(start.x,2*origen.y-start.y,0);          //for cacheing the last point

        Vector3f displacement = new Vector3f(end.x,end.y,end.z);            //displacement vector
        displacement.sub(new Vector3f(start.x,start.y,start.z));

        float stretchedLength = displacement.length();                 //lengthof Spring
        displacement.normalize();
        float sin = displacement.y, cos = displacement.x;       //direction of Spring
//                sin=0;cos=1;
//                System.out.println("direction=" +displacement);
//                g.drawLine((int)start.x, 400-(int)start.y, (int)(start.x+cos*length), 400-(int)(start.y+sin*length));
        //graph xt=t yt=sin(t) then transform
        for (float i = 0; i < 1; i += .1f/COILS) {
            Vector3f current = new Vector3f(i*stretchedLength, (float) (20 * Math.sin(COILS*Math.PI*i)),0);
            Vector3f rotated = new Vector3f(current.x * cos - current.y * sin,
                    +current.x * sin + current.y * cos,0);
            Vector3f translated = new Vector3f(rotated.x + start.x,2*origen.y-start.y- rotated.y,0);
            g.drawLine((int) (translated.x), (int) (translated.y), (int) (last.x), (int) (last.y));
            last = (Vector3f) translated.clone();
        }
    }



    @Override
    public Vector3f getAcceleration(State state, float t) {

        //return -k * (state.position.x-400) - b*state.v.x;
        Vector3f force ;
        Vector3f displacement ;
        displacement=(Vector3f) state.getPosition().clone() ;
        displacement.sub(new Vector3f(start.x,start.y,start.z));

        float StretchedLength = displacement.length();
        force=(Vector3f) displacement.clone();
        force.normalize();

        float offset = StretchedLength - length;
        float f = (-stiffness * (offset-1e4f/StretchedLength));
        Vector3f dampening ;
        force.scale(f);
        dampening=(Vector3f) state.getVelocity().clone();
        dampening.scale(dampeningFactor);

        force.sub(dampening);
//         System.out.println("force = " + force);
        return force;
    }

    @Override
    public Vector3f getAppliedForce(Element acc, float t) {
        return getAcceleration(acc.getState(), t);
    }


    @Override
    public boolean collides(Vector3f point) {
       boolean collides;
       double dist= (StrictMath.hypot(point.x-start.x, point.y-start.y));
       collides=dist<20;
        return collides;
    }


    @Override
    public Rectangle getBounds() {
        return new Rectangle();
    }

    @Override
    public Vector3f getMaxInDir(Vector3f dir) {
        return new Vector3f();
    }

    @Override
    public boolean isPassive() {
        return  true;
    }
}
